package com.aerozhonghuan.archive.service.impl;

import com.aerozhonghuan.archive.config.DynamicDataSourceHolder;
import com.aerozhonghuan.archive.dto.UpdateResult;
import com.aerozhonghuan.archive.entity.MigrationConfig;
import com.aerozhonghuan.archive.mapper.ArchiveMigrationConfigMapper;
import com.aerozhonghuan.archive.mapper.SourceMapper;
import com.aerozhonghuan.archive.service.ConfigUpdateService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class ConfigUpdateServiceImpl implements ConfigUpdateService {

    private static final Logger logger = LoggerFactory.getLogger(ConfigUpdateServiceImpl.class);

    private final ArchiveMigrationConfigMapper migrationConfigMapper;
    private final SourceMapper sourceMapper;

    public ConfigUpdateServiceImpl(ArchiveMigrationConfigMapper migrationConfigMapper, SourceMapper sourceMapper) {
        this.migrationConfigMapper = migrationConfigMapper;
        this.sourceMapper = sourceMapper;
    }

    /**
     * 更新归档库中的配置表
     */
    @Override
    public List<UpdateResult> updateAllLastCreateTime() {

        List<MigrationConfig> configs = migrationConfigMapper.getAllEnabled();
        List<UpdateResult> results = new ArrayList<>();

        if (configs == null || configs.isEmpty()) {
            logger.warn("未查询到启用的迁移配置记录。");
            return results;
        }

        for (MigrationConfig config : configs) {
            UpdateResult updateResult = new UpdateResult();
            updateResult.setConfigId(config.getId());
            updateResult.setSourceDbName(config.getSourceDbName());
            updateResult.setSourceTableName(config.getSourceTableName());
            updateResult.setTargetDbName(config.getTargetDbName());
            updateResult.setTargetTableName(config.getTargetTableName());
            updateResult.setOldLastCreateTime(config.getLastCreateTime());
            try {
                // 从源库查询最大时间，动态切换到配置记录中指定的源数据源
                Date maxTime = getSourceMaxTime(
                        config.getSourceDbName(),
                        config.getSourceTableName(),
                        config.getTimeStamp(),
                        config.getSourceDatasource()
                );
                if (maxTime != null) {
                    // 切换到归档数据源
                    DynamicDataSourceHolder.setDynamicDataSourceKey(config.getTargetDatasource());
                    int updated = migrationConfigMapper.updateLastCreateTime(config.getId(), maxTime);
                    if (updated > 0) {
                        updateResult.setNewLastCreateTime(maxTime);
                        updateResult.setSuccess(true);
                        updateResult.setMessage("更新成功");
                        logger.info("配置记录 id {} 更新成功，新时间：{}", config.getId(), maxTime);
                    } else {
                        updateResult.setSuccess(false);
                        updateResult.setMessage("未更新任何记录");
                        logger.warn("配置记录 id {} 未更新任何记录", config.getId());
                    }
                } else {
                    updateResult.setSuccess(false);
                    updateResult.setMessage("源表中无记录，未获取到最大时间");
                    logger.warn("配置记录 id {} 源表中无记录，未获取到最大时间", config.getId());
                }
            } catch (Exception e) {
                logger.error("更新配置记录 id {} 时出错", config.getId(), e);
                updateResult.setSuccess(false);
                updateResult.setMessage("更新异常: " + e.getMessage());
            }
            results.add(updateResult);
        }
        return results;
    }

    /**
     * 从源数据源查询指定表中指定时间字段的最大值
     *
     * @param schemaName      数据库名
     * @param tableName       表名
     * @param timeStampColumn 时间字段名
     * @param sourceDatasource 源数据源标识
     * @return 返回最大时间，若查询失败则返回 null
     */
    private Date getSourceMaxTime(String schemaName, String tableName, String timeStampColumn, String sourceDatasource) {
        // 根据配置动态切换到对应的源数据源
        DynamicDataSourceHolder.setDynamicDataSourceKey(sourceDatasource);
        Date maxTime = sourceMapper.getMaxTime(schemaName, tableName, timeStampColumn);
        logger.debug("getSourceMaxTime执行，数据库: {}, 表: {}, 时间字段: {}, 使用数据源: {}, 返回最大时间: {}",
                schemaName, tableName, timeStampColumn, sourceDatasource, maxTime);
        return maxTime;
    }
}
